/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.editor; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Enumeration; import javax.swing.text.JTextComponent; /** * All the documents and components register here so that * they become available to the processing that crosses * different components and documents such as cross document * position stack or word matching. * * @author Miloslav Metelka * @version 1.00 */ public class Registry { /** Shared iregistry nstance */ private static Registry registry; /** Array list of weak references to documents */ private ArrayList docRefs = new ArrayList(); /** Array of activated document numbers */ private ArrayList docAct = new ArrayList(); /** Array list of weak references to components */ private ArrayList compRefs = new ArrayList(); /** Array of activated component numbers */ private ArrayList compAct = new ArrayList(); /** Get shared registry instance */ public static Registry getRegistry() { if (registry == null) { registry = new Registry(); } return registry; } /** Add document to registry. Doesn't search for repetitive * adding. * @return ID of the component */ public static synchronized int addDocument(BaseDocument doc) { Registry r = getRegistry(); int ind = getID(doc); if (ind != -1) { return ind; } ind = r.docRefs.size(); r.docRefs.add(new WeakReference(doc)); doc.putProperty(BaseDocument.ID_PROP, new Integer(ind)); return ind; } /** Get documeent ID from the document by searching for ID property */ public static synchronized int getID(BaseDocument doc) { if (doc == null) { return -1; } Integer ind = (Integer)doc.getProperty(BaseDocument.ID_PROP); if (ind == null) { return -1; } else { return ind.intValue(); } } /** Get document when its ID is known. * It's rather cheap operation. * @return document instance or null when document no longer exists */ public static synchronized BaseDocument getDocument(int docID) { Registry r = getRegistry(); if (docID > r.docRefs.size()) { return null; } return (BaseDocument)((WeakReference)r.docRefs.get(docID)).get(); } /** Put the document to the first position in the array of last accessed * documents. */ public static synchronized void activate(BaseDocument doc) { int docID = getID(doc); if (docID == -1) { // doc not registered return; } Integer i = new Integer(docID); Registry r = getRegistry(); int ind = r.docAct.indexOf(i); if (ind != -1) { r.docAct.add(0, r.docAct.remove(ind)); } else { // not yet added r.docAct.add(0, i); } } private BaseDocument getValidDoc(int ind, boolean forward) { while (ind >= 0 && ind < docAct.size()) { int docID = ((Integer)docAct.get(ind)).intValue(); BaseDocument doc = (BaseDocument)((WeakReference)docRefs.get(docID)).get(); if (doc != null) { return doc; } else { // non-existent component, remove from activated list docAct.remove(ind); ind -= forward ? +1 : -1; // continue stmt gives unreachable code - bug? } ind += forward ? +1 : -1; } return null; } private BaseDocument getNextActiveDoc(int docID, boolean forward) { int actSize = docAct.size(); int ind = forward ? 0 : (actSize - 1); while (ind >= 0 && ind < actSize) { if (((Integer)docAct.get(ind)).intValue() == docID) { ind += forward ? +1 : -1; // get next one return getValidDoc(ind, forward); } ind += forward ? +1 : -1; } return null; } public static synchronized BaseDocument getMostActiveDocument() { return getRegistry().getValidDoc(0, true); } public static synchronized BaseDocument getLeastActiveDocument() { int lastInd = getRegistry().docAct.size() - 1; return getRegistry().getValidDoc(lastInd, false); } public static BaseDocument getLessActiveDocument(BaseDocument doc) { return getLessActiveDocument(getID(doc)); } public static synchronized BaseDocument getLessActiveDocument(int docID) { return getRegistry().getNextActiveDoc(docID, true); } public static BaseDocument getMoreActiveDocument(BaseDocument doc) { return getMoreActiveDocument(getID(doc)); } public static synchronized BaseDocument getMoreActiveDocument(int docID) { return getRegistry().getNextActiveDoc(docID, false); } /** Add component to registry. If the component is already registered * it returns the existing ID. * @return ID of the component */ public static synchronized int addComponent(JTextComponent c) { Registry r = getRegistry(); int ind = getID(c); if (ind != -1) { return ind; // already registered } ind = r.compRefs.size(); r.compRefs.add(new WeakReference(c)); ((BaseTextUI)c.getUI()).getExtUI().componentID = ind; return ind; } /** Get documeent ID from the document by searching for ID property */ public static synchronized int getID(JTextComponent c) { if (c == null) { return -1; } return ((BaseTextUI)c.getUI()).getExtUI().componentID; } /** Get component when its ID is known. * It's rather cheap operation. * @return component instance or null when component no longer exists */ public static synchronized JTextComponent getComponent(int compID) { Registry r = getRegistry(); if (compID > r.compRefs.size()) { return null; } return (JTextComponent)((WeakReference)r.compRefs.get(compID)).get(); } /** Put the component to the first position in the array of last accessed * components. The activate of document is also called automatically. */ public static synchronized void activate(JTextComponent c) { int compID = getID(c); if (compID == -1) { // c not registered return; } Integer i = new Integer(compID); Registry r = getRegistry(); int ind = r.compAct.indexOf(i); if (ind != -1) { r.compAct.add(0, r.compAct.remove(ind)); } else { // not yet added r.compAct.add(0, i); } activate((BaseDocument)c.getDocument()); // activate document too } private JTextComponent getValidComp(int ind, boolean forward) { while (ind < compAct.size() && ind >= 0) { int compID = ((Integer)compAct.get(ind)).intValue(); JTextComponent c = (JTextComponent)((WeakReference)compRefs.get(compID)).get(); if (c != null) { return c; } else { // non-existent component, remove from activated list compAct.remove(ind); ind -= forward ? +1 : -1; // continue stmt gives unreachable code - bug? } ind += forward ? +1 : -1; } return null; } private JTextComponent getNextActiveComp(int compID, boolean forward) { int actSize = compAct.size(); int ind = forward ? 0 : (actSize - 1); while (ind >= 0 && ind < actSize) { if (((Integer)compAct.get(ind)).intValue() == compID) { ind += forward ? +1 : -1; return getValidComp(ind, forward); } ind += forward ? +1 : -1; } return null; } public static synchronized JTextComponent getMostActiveComponent() { return getRegistry().getValidComp(0, true); } public static synchronized JTextComponent getLeastActiveComponent() { int lastInd = getRegistry().compAct.size() - 1; return getRegistry().getValidComp(lastInd, false); } public static JTextComponent getLessActiveComponent(JTextComponent c) { return getLessActiveComponent(getID(c)); } public static synchronized JTextComponent getLessActiveComponent(int compID) { return getRegistry().getNextActiveComp(compID, true); } public static JTextComponent getMoreActiveComponent(JTextComponent c) { return getMoreActiveComponent(getID(c)); } public static synchronized JTextComponent getMoreActiveComponent(int compID) { return getRegistry().getNextActiveComp(compID, false); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append("Document References:\n"); // NOI18N for (int i = 0; i < docRefs.size(); i++) { WeakReference r = (WeakReference)docRefs.get(i); sb.append("docRefs[" + i + "]=" + ((r != null) ? r.get() : "null") + "\n\n"); // NOI18N } sb.append("Component References:\n"); // NOI18N for (int i = 0; i < compRefs.size(); i++) { WeakReference r = (WeakReference)compRefs.get(i); sb.append("compRefs[" + i + "]=" + ((r != null) ? r.get() : "null") + "\n\n"); // NOI18N } sb.append("\nActive Document Indexes:\n"); // NOI18N for (int i = 0; i < docAct.size(); i++) { sb.append(docAct.get(i)); if (i != docAct.size() - 1) { sb.append(", "); // NOI18N } } sb.append("\nActive Component Indexes:\n"); // NOI18N for (int i = 0; i < compAct.size(); i++) { sb.append(compAct.get(i)); if (i != compAct.size() - 1) { sb.append(", "); // NOI18N } } return sb.toString(); } } /* * Log * 6 Gandalf 1.5 1/13/00 Miloslav Metelka * 5 Gandalf 1.4 11/8/99 Miloslav Metelka * 4 Gandalf 1.3 10/23/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 3 Gandalf 1.2 5/7/99 Miloslav Metelka line numbering and fixes * 2 Gandalf 1.1 5/5/99 Miloslav Metelka * 1 Gandalf 1.0 4/23/99 Miloslav Metelka * $ */